//
//  UIViewAdditions.m
//  Weibo
//
//  Created by junmin liu on 10-9-29.
//  Copyright 2010 Openlab. All rights reserved.
//

#import <QuartzCore/QuartzCore.h>
#import "UIViewAdditions.h"
#import <objc/runtime.h>

static const void *UIViewTapBlockKey                           = &UIViewTapBlockKey;
static const void *UIViewTapGestureEvent                       = &UIViewTapGestureEvent;

static const void *UIViewLongPressBlockKey                           = &UIViewLongPressBlockKey;
static const void *UIViewLongPressGestureEvent                       = &UIViewLongPressGestureEvent;

@implementation UIView (Addtions)

- (id)roundCornersOnTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius {
    self.clipsToBounds = YES;
    if (tl || tr || bl || br) {
        UIRectCorner corner = 0; //holds the corner
        //Determine which corner(s) should be changed
        if (tl) {
            corner = UIRectCornerTopLeft;
        }
        if (tr) {
            UIRectCorner add = corner | UIRectCornerTopRight;
            corner = add;
        }
        if (bl) {
            UIRectCorner add = corner | UIRectCornerBottomLeft;
            corner = add;
        }
        if (br) {
            UIRectCorner add = corner | UIRectCornerBottomRight;
            corner = add;
        }
        
        UIView *roundedView = self;
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:roundedView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.frame = roundedView.bounds;
        maskLayer.path = maskPath.CGPath;
        roundedView.layer.mask = maskLayer;
        return roundedView;
    } else {
        return self;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)left {
	return self.frame.origin.x;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setLeft:(CGFloat)x {
	CGRect frame = self.frame;
	frame.origin.x = x;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)top {
	return self.frame.origin.y;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setTop:(CGFloat)y {
	CGRect frame = self.frame;
	frame.origin.y = y;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)right {
	return self.frame.origin.x + self.frame.size.width;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setRight:(CGFloat)right {
	CGRect frame = self.frame;
	frame.origin.x = right - frame.size.width;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)bottom {
	return self.frame.origin.y + self.frame.size.height;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setBottom:(CGFloat)bottom {
	CGRect frame = self.frame;
	frame.origin.y = bottom - frame.size.height;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)centerX {
	return self.center.x;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setCenterX:(CGFloat)centerX {
	self.center = CGPointMake(centerX, self.center.y);
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)centerY {
	return self.center.y;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setCenterY:(CGFloat)centerY {
	self.center = CGPointMake(self.center.x, centerY);
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)width {
	return CGRectGetWidth(self.frame);
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setWidth:(CGFloat)width {
	CGRect frame = self.frame;
	frame.size.width = width;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)height {
	return CGRectGetHeight(self.frame);
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setHeight:(CGFloat)height {
	CGRect frame = self.frame;
	frame.size.height = height;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)ttScreenX {
	CGFloat x = 0;
	for (UIView* view = self; view; view = view.superview) {
		x += view.left;
	}
	return x;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)ttScreenY {
	CGFloat y = 0;
	for (UIView* view = self; view; view = view.superview) {
		y += view.top;
	}
	return y;
}



///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)screenViewX {
	CGFloat x = 0;
	for (UIView* view = self; view; view = view.superview) {
		x += view.left;
		
		if ([view isKindOfClass:[UIScrollView class]]) {
			UIScrollView* scrollView = (UIScrollView*)view;
			x -= scrollView.contentOffset.x;
		}
	}
	
	return x;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)screenViewY {
	CGFloat y = 0;
	for (UIView* view = self; view; view = view.superview) {
		y += view.top;
		
		if ([view isKindOfClass:[UIScrollView class]]) {
			UIScrollView* scrollView = (UIScrollView*)view;
			y -= scrollView.contentOffset.y;
		}
	}
	return y;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGRect)screenFrame {
	return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height);
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGPoint)origin {
	return self.frame.origin;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setOrigin:(CGPoint)origin {
	CGRect frame = self.frame;
	frame.origin = origin;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGFloat)originY {
	return self.frame.origin.y;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setOriginY:(CGFloat)originY {
	CGRect frame = self.frame;
	frame.origin.y = originY;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (CGSize)size {
	return self.frame.size;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setSize:(CGSize)size {
	CGRect frame = self.frame;
	frame.size = size;
	self.frame = frame;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (UIView*)descendantOrSelfWithClass:(Class)cls {
	if ([self isKindOfClass:cls])
		return self;
	
	for (UIView* child in self.subviews) {
		UIView* it = [child descendantOrSelfWithClass:cls];
		if (it)
			return it;
	}
	
	return nil;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (UIView*)ancestorOrSelfWithClass:(Class)cls {
	if ([self isKindOfClass:cls]) {
		return self;
	} else if (self.superview) {
		return [self.superview ancestorOrSelfWithClass:cls];
	} else {
		return nil;
	}
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)removeAllSubviews {
	while (self.subviews.count) {
		UIView* child = self.subviews.lastObject;
		[child removeFromSuperview];
	}
}

////////////////
- (UIImage *)imageByRenderingView {
	
    CGSize size = self.bounds.size;
    //size.width = size.width/2;
    //size.height = size.height/2;
    
	UIGraphicsBeginImageContext(size);
	[self.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	
	return resultingImage;
}

- (UIImage*)screenshot {
    UIGraphicsBeginImageContext(self.bounds.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // hack, helps w/ our colors when blurring
    NSData *imageData = UIImageJPEGRepresentation(image, 1); // convert to jpeg
    image = [UIImage imageWithData:imageData];
    
    return image;
}

- (UIImage*)screenshotOptions{
    // 下面方法
    //第一个参数表示区域大小
    //第二个参数表示是否是非透明的。如果需要显示半透明效果，需要传NO，否则传YES。
    //第三个参数就是屏幕密度了，关键就是第三个参数 [UIScreen mainScreen].scale。
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, 0, [UIScreen mainScreen].scale);  //0.0
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

- (UIImage*)screenshotWithSize:(CGSize)size {
    UIGraphicsBeginImageContext(size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    // hack, helps w/ our colors when blurring
    NSData *imageData = UIImageJPEGRepresentation(image, 1); // convert to jpeg
    image = [UIImage imageWithData:imageData];
    
    return image;
}

#pragma mark - 添加 Tap手势 Block回调
- (void)setTapResultBlock:(UIViewTapResultBlock)tapResultBlock{
    objc_setAssociatedObject(self, UIViewTapBlockKey, tapResultBlock, OBJC_ASSOCIATION_COPY);
    if (tapResultBlock && self.userInteractionEnabled == NO) {
        self.userInteractionEnabled = YES;
    }
    
    self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(TapGestureEvent)];
    self.tapGestureRecognizer.cancelsTouchesInView = NO;
    [self addGestureRecognizer:self.tapGestureRecognizer];
}


//添加 block属性
- (UIViewTapResultBlock)tapResultBlock{
    return objc_getAssociatedObject(self, UIViewTapBlockKey);
}

//添加 tap手势
- (void)setTapGestureRecognizer:(UITapGestureRecognizer *)tapGestureRecognizer{
    objc_setAssociatedObject(self, UIViewTapGestureEvent, tapGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}


- (UITapGestureRecognizer *)tapGestureRecognizer{
    return objc_getAssociatedObject(self, UIViewTapGestureEvent);
}

//tap点击事件
- (void)TapGestureEvent{
    if (self.tapResultBlock) {
        self.tapResultBlock(YES);
    }
}

#pragma mark - 长按手势
- (void)setLongPressResultBlock:(UIViewLongPressResultBlock)longPressResultBlock{
    objc_setAssociatedObject(self, UIViewLongPressBlockKey, longPressResultBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    self.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(LongPressEvent)];
    self.longPressGestureRecognizer.minimumPressDuration = 0.5;
    [self addGestureRecognizer:self.longPressGestureRecognizer];
}

- (UIViewLongPressResultBlock)longPressResultBlock{
    return objc_getAssociatedObject(self, UIViewLongPressBlockKey);
}

- (void)setLongPressGestureRecognizer:(UILongPressGestureRecognizer *)longPressGestureRecognizer{
    objc_setAssociatedObject(self, UIViewLongPressGestureEvent, longPressGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UILongPressGestureRecognizer *)longPressGestureRecognizer{
    return objc_getAssociatedObject(self, UIViewLongPressGestureEvent);
}

- (void)LongPressEvent{
    if (self.longPressGestureRecognizer.state == UIGestureRecognizerStateBegan ) {
        self.longPressResultBlock(YES);
    }
}

#pragma mark - 占位图

static const void *UIViewPlaceholderKey     = &UIViewPlaceholderKey;

/** 显示占位图片 */
- (void)showPlaceholderView:(BOOL)show text:(NSString *)text image:(UIImage *)image{
    
    if (show) {
        if (text) {
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, self.height/4.0, (self.width-20*2), 30)];
            label.numberOfLines = 0;
            label.autoresizingMask =
            UIViewAutoresizingFlexibleWidth |
            UIViewAutoresizingFlexibleLeftMargin |
            UIViewAutoresizingFlexibleRightMargin;
            
            if ([text isKindOfClass:[NSAttributedString class]]) {
                [label setAttributedText:(NSAttributedString * _Nullable)text];
            }else{
                [label setText:text];
                label.textColor = [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1.0];
            }
            label.textAlignment = NSTextAlignmentCenter;
            
            [self.placeHolderView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
            [self.placeHolderView addSubview:label];
            
            [self.placeHolderView setHidden:NO];
        }
        if (image) {
            self.placeHolderView.layer.contents = (id)image.CGImage;
        }
        
        [self bringSubviewToFront:self.placeHolderView];
    }else{
        //隐藏
        if (self.placeHolderView) {
            [self.placeHolderView setHidden:YES];
        }
    }
}

- (UIView *)placeHolderView{
    UIView *view = objc_getAssociatedObject(self, UIViewPlaceholderKey);
    if (!view) {
        view = [[UIView alloc] initWithFrame:self.bounds];
        view.autoresizingMask =
        UIViewAutoresizingFlexibleTopMargin |
        UIViewAutoresizingFlexibleBottomMargin |
        UIViewAutoresizingFlexibleLeftMargin |
        UIViewAutoresizingFlexibleRightMargin |
        UIViewAutoresizingFlexibleWidth |
        UIViewAutoresizingFlexibleHeight;
        
        view.backgroundColor = [UIColor colorWithRed:245/255.0 green:245/255.0 blue:245/255.0 alpha:1.0];
        [self addSubview:view];
        
        objc_setAssociatedObject(self, UIViewPlaceholderKey, view, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    return view;
}

- (void)setPlaceHolderView:(UIView *)placeHolderView{
    objc_setAssociatedObject(self, UIViewPlaceholderKey, placeHolderView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - XIB
+ (instancetype)viewFromXib
{
    Class viewClass = [self class];
    NSString *viewClassName = NSStringFromClass(viewClass);
    NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:viewClassName owner:nil options:nil];
    
    for (id nibItem in nibArray) {
        if ([nibItem isMemberOfClass:viewClass]) {
            return nibItem;
        }
    }
    
    return nil;
}


- (void)addSubviews:(NSArray *)objects{
    
    for (UIView *view in objects) {
        [self addSubview:view];
    }
}

@end
